package com.freeman.cement.util;


import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.apache.commons.lang3.time.DateUtils;

public class JwtUtil {
    /**
     * token加密时使用的密钥
     * 一旦得到该密钥也就可以伪造token了
     */
    public static String MyKey = "05318e9bf5b540539d6903362205297d";
    /**
     * 代表token的有效时间，单位秒
     */
    public final static int keeptime = 10 * 60 * 60;    //10小时

    //生成token
    public static String generateToken(String userId, String userRole, String subject)
    {
        //创建SecretKey
        SecretKey secretKey = Keys.hmacShaKeyFor(MyKey.getBytes(StandardCharsets.UTF_8));

        //定义私有payload
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        map.put("userRole", userRole);
        //过期时间
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, keeptime);
        //生成jws，也就是token
        String token= Jwts.builder()
                .setSubject(subject)
                .setExpiration(calendar.getTime())
                .setNotBefore(new Date())//生效时间为当前时间
                .setIssuedAt(new Date())//签发时间
                .addClaims(map) //使用addClaims不会覆盖掉setSubject("")
                .signWith(secretKey, SignatureAlgorithm.HS256)
                .compressWith(CompressionCodecs.DEFLATE)
                .compact();
        return token;
    }

    //更新token
    public static String updateToken(String token) {
        //Claims就是包含了我们的Payload信息类
        Claims body = verify(token);
        String subject = body.getSubject();
        String userId = body.get("userId").toString();
        String userRole = body.get("userRole").toString();
        //生成新的token,根据现在的时间
        return generateToken(userId, userRole, subject);
    }

    //校验token
    public static Claims verify(String token)
    {
        Claims body = null;
        SecretKey secretKey = Keys.hmacShaKeyFor(MyKey.getBytes(StandardCharsets.UTF_8));
        try
        {
            Jws<Claims> claims = Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token);
            //读取数据
            body = claims.getBody();
            String subject = body.getSubject();
            Object userId = body.get("userId");
            Object userRole = body.get("userRole");
            System.out.println("verify pass, subject = " + subject + ", userId = " + userId.toString() + ", userRole = " + userRole.toString());
        }
        catch (io.jsonwebtoken.security.SignatureException se)
        {
            System.out.println("===SignatureException===");
            se.printStackTrace();
            throw se;
        }
        catch (io.jsonwebtoken.security.KeyException ke)
        {
            System.out.println("===KeyException===");
            ke.printStackTrace();
            throw ke;
        }
        catch (ExpiredJwtException ee)
        {
            System.out.println("===ExpiredJwtException===");
            ee.printStackTrace();
            throw ee;
        }
        catch (InvalidClaimException ie)
        {
            System.out.println("===InvalidClaimException===");
            ie.printStackTrace();
            throw ie;
        }
        catch (CompressionException ce)
        {
            System.out.println("===CompressionException===");
            ce.printStackTrace();
            throw ce;
        }
        catch (JwtException je)
        {
            System.out.println("===JwtException===");
            je.printStackTrace();
            throw je;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            throw e;
        }
        return body;
    }

}
